package com.lu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lu.mapper.SysBrandMapper;
import com.lu.mapper.SysMerchantMapper;
import com.lu.mapper.SysStoreMapper;
import com.lu.mapper.SysUserMapper;
import com.lu.model.entity.SysBrand;
import com.lu.model.entity.SysMerchant;
import com.lu.model.entity.SysStore;
import com.lu.model.entity.SysUser;
import com.lu.model.enums.ApprovalStatusEnum;
import com.lu.model.exception.LuBootAssert;
import com.lu.model.request.MerchantAddRequest;
import com.lu.model.request.MerchantQueryRequest;
import com.lu.model.request.UserAddRequest;
import com.lu.service.SysMerchantService;
import com.lu.service.SysUserService;
import com.lu.utils.SecurityUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商户 服务实现类
 * </p>
 *
 * @author currentCodeAuthor
 * @since 2022-07-31
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysMerchantServiceImpl extends ServiceImpl<SysMerchantMapper, SysMerchant> implements SysMerchantService {

  private final SysBrandMapper brandMapper;
  private final SysStoreMapper storeMapper;
  private final SysUserService userService;
  private final SysUserMapper userMapper;

  @Override
  public PageInfo<SysMerchant> pageList(MerchantQueryRequest request) {
    PageHelper.startPage(request.getPageIndex(), request.getPageSize())
            .setOrderBy("sm.sort,sm.create_time desc");
    PageInfo<SysMerchant> merchantPage = PageInfo.of(this.baseMapper.list(request));
    List<SysMerchant> merchantList = merchantPage.getList();
    if(ObjectUtil.isEmpty(merchantList)){
      return merchantPage;
    }
    //品牌名
    QueryWrapper<SysBrand> brandQueryWrapper = new QueryWrapper<>();
    brandQueryWrapper.select("id", "name");
    brandQueryWrapper.in("id", merchantList.stream().map(SysMerchant::getBrandId).collect(Collectors.toList()));
    Map<Long, List<SysBrand>> brandMap = brandMapper.selectList(brandQueryWrapper).stream().collect(Collectors.groupingBy(SysBrand::getId));
    for (SysMerchant merchant : merchantList) {
      List<SysBrand> brandList = brandMap.get(merchant.getBrandId());
      if(ObjectUtil.isNotEmpty(brandList) && ObjectUtil.isNotEmpty(brandList.get(0).getName())){
        merchant.setBrandName(brandList.get(0).getName());
      }
    }
    QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
    userQueryWrapper.select("id", "username");
    userQueryWrapper.in("id", merchantList.stream().map(SysMerchant::getUserId).collect(Collectors.toList()));
    Map<Long, List<SysUser>> userMap = userMapper.selectList(userQueryWrapper).stream().collect(Collectors.groupingBy(SysUser::getId));
    for (SysMerchant merchant : merchantList) {
      //品牌下的商户的线下门店
      List<SysUser> users = userMap.get(merchant.getUserId());
      if(ObjectUtil.isNotEmpty(users)){
        merchant.setUsername(users.get(0).getUsername());
      }
    }
    QueryWrapper<SysStore> storeQueryWrapper = new QueryWrapper<>();
    storeQueryWrapper.select("id", "relation_id");
    storeQueryWrapper.eq("business_mode", SysStore.BusinessMode.OFFLINE.getMode());
    storeQueryWrapper.isNotNull("relation_id");
    storeQueryWrapper.in("relation_id", merchantList.stream().map(SysMerchant::getId).collect(Collectors.toList()));
    List<SysStore> storesByMerchant = storeMapper.selectList(storeQueryWrapper);
    if(ObjectUtil.isEmpty(storesByMerchant)){
      return merchantPage;
    }
    Map<Long, List<SysStore>> storesByMerchantMap = storesByMerchant.stream().collect(Collectors.groupingBy(SysStore::getRelationId));
    for (SysMerchant merchant : merchantList) {
      //品牌下的商户的线下门店
      List<SysStore> storeByMerchantList = storesByMerchantMap.get(merchant.getId());
      if(ObjectUtil.isNotEmpty(storeByMerchantList)){
        merchant.setStoreCount(ObjectUtil.isEmpty(merchant.getStoreCount()) ? 0 : merchant.getStoreCount());
        merchant.setStoreCount(merchant.getStoreCount() + storeByMerchantList.size());
      }
    }
    return merchantPage;
  }

  @Override
  public List<SysMerchant> merchantList(MerchantQueryRequest request) {
    List<SysMerchant> merchantList = this.baseMapper.list(request);
    return merchantList;
  }

  @Transactional(rollbackFor = Exception.class)
  @Override
  public Long addMerchant(MerchantAddRequest request) {
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(request.getStatus())
        && Arrays.stream(ApprovalStatusEnum.values()).anyMatch(o -> o.getStatus() == request.getStatus()), "无效的状态参数");
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(request.getBusinessMode())
        && Arrays.stream(SysMerchant.BusinessMode.values()).anyMatch(o -> o.getMode() == request.getBusinessMode()), "无效的经营模式参数");
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(request.getStoreType())
        && Arrays.stream(SysMerchant.StoreType.values()).anyMatch(o -> o.getType() == request.getStoreType()), "无效的店铺类型参数");
//    this.checkPhoneUnique(null, request.getContactsPhone());
    this.checkNameUnique(null, request.getName());
    //新增用户，创建好账号
    UserAddRequest addRequest = new UserAddRequest();
    addRequest.setUsername(request.getUsername());
    addRequest.setPassword(request.getPassword());
    addRequest.setRealName(request.getContactsName());
    addRequest.setCompany(request.getName());
    Long userId = userService.addUser(addRequest);
    //新增商户
    SysMerchant merchant = new SysMerchant();
    BeanUtil.copyProperties(request, merchant);
    merchant.setUserId(userId);
    merchant.setCreateUserId(SecurityUtil.getCurrentUser().getId());
    merchant.setUpdateUserId(SecurityUtil.getCurrentUser().getId());
    this.baseMapper.insert(merchant);
    return merchant.getId();
  }

  @Override
  public SysMerchant updateMerchant(SysMerchant merchant) {
    LuBootAssert.isTrue(ObjectUtil.isNotEmpty(merchant.getId()), "修改失败");
    LuBootAssert.isTrue(ObjectUtil.isEmpty(merchant.getStatus())
        || Arrays.stream(ApprovalStatusEnum.values()).anyMatch(o -> o.getStatus() == merchant.getStatus()), "无效的状态参数");
    LuBootAssert.isTrue(ObjectUtil.isEmpty(merchant.getBusinessMode())
        || Arrays.stream(SysMerchant.BusinessMode.values()).anyMatch(o -> o.getMode() == merchant.getBusinessMode()), "无效的经营模式参数");
    LuBootAssert.isTrue(ObjectUtil.isEmpty(merchant.getStoreType())
        || Arrays.stream(SysMerchant.StoreType.values()).anyMatch(o -> o.getType() == merchant.getStoreType()), "无效的店铺类型参数");
    this.checkNameUnique(merchant.getId(), merchant.getName());
    merchant.setUpdateUserId(SecurityUtil.getCurrentUser().getId());
    merchant.setUpdateTime(LocalDateTime.now());
    this.baseMapper.updateById(merchant);
    return this.baseMapper.selectById(merchant.getId());
  }

  @Override
  public String delete(Long id) {
    SysMerchant merchant = this.baseMapper.selectById(id);
    //删除用户
    String rs = userService.deleteUser(merchant.getUserId());
    //删除商户
    int res = this.baseMapper.deleteById(id);
    return res + "==" + rs;
  }

  private void checkPhoneUnique(Long id, String phone){
    if(ObjectUtil.isEmpty(phone)){
      return;
    }
    QueryWrapper<SysMerchant> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("contacts_phone", phone);
    if(ObjectUtil.isNotEmpty(id)){
      queryWrapper.ne("id", id);
    }
    Integer count = this.baseMapper.selectCount(queryWrapper);
    LuBootAssert.isTrue(count == 0, "联系人手机号不能重复");
  }

  private void checkNameUnique(Long id, String name){
    if(ObjectUtil.isEmpty(name)){
      return;
    }
    QueryWrapper<SysMerchant> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("name", name);
    if(ObjectUtil.isNotEmpty(id)){
      queryWrapper.ne("id", id);
    }
    Integer count = this.baseMapper.selectCount(queryWrapper);
    LuBootAssert.isTrue(count == 0, "名称不能重复");
  }

}
